package cn.restcloud.example.controller.elasticsearch;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.bson.Document;
import org.elasticsearch.action.admin.indices.get.GetIndexResponse;
import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.metadata.MappingMetaData;
import org.elasticsearch.common.collect.ImmutableOpenMap;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;

import com.alibaba.fastjson.JSON;
import com.carrotsearch.hppc.cursors.ObjectCursor;
import com.carrotsearch.hppc.cursors.ObjectObjectCursor;

import cn.restcloud.framework.core.annotation.bean.BeanConfig;
import cn.restcloud.framework.core.annotation.bean.BeanType;
import cn.restcloud.framework.core.annotation.rest.MethodType;
import cn.restcloud.framework.core.annotation.rest.Param;
import cn.restcloud.framework.core.annotation.rest.Params;
import cn.restcloud.framework.core.annotation.rest.RestConfig;
import cn.restcloud.framework.core.util.DateTimeUtil;
import cn.restcloud.framework.core.util.DocumentUtil;
import cn.restcloud.framework.core.util.JsonPathUtil;
import cn.restcloud.framework.core.util.JsonUtil;
import cn.restcloud.framework.core.util.PrintUtil;
import cn.restcloud.framework.core.util.db.elasticsearch.ElasticsearchUtil;
import cn.restcloud.framework.view.base.DocAndView;
import cn.restcloud.framework.view.util.ViewUtil;

@BeanConfig(appId = "example",beanId = "ElasticsearchRest",beanName = "ElasticsearchRest读写示例",beanType = BeanType.CONTROLLER,autowired = false,singleton = true,hotMode = true)
@RestConfig(url = "/rest/example/es")
public class ElasticsearchRest {
	String index = "testindex";
	String type = "users";
	
	@RestConfig(configName = "查询数据",method = MethodType.POST,url = "/findall")
	@Params({
		@Param(id = "index", name = "index",required=true),
		@Param(id = "type", name = "type",required=true),
	})
	public DocAndView findAll(String index,String type) throws Exception{
		Client client=ElasticsearchUtil.getClient();
		List<Document> docs=ElasticsearchUtil.listAllDocs(client, index, type, "", true,"id",1000);
		return ViewUtil.getJsonView(docs);
	}
	
	@RestConfig(configName = "更新数据",method = MethodType.POST,url = "/updatedoc")
	public DocAndView updatedoc() throws Exception{
		Client client=ElasticsearchUtil.getClient();
		Document doc1=new Document();
		doc1.put("name", "刘军0000085");
		doc1.put("num", 5);
		doc1.put("begin_date", "2019-02-10 06:06:06");
		doc1.put("id","9002");
		UpdateResponse r=ElasticsearchUtil.updateDocById(client, index, type, "9002", doc1);
		return ViewUtil.getJsonView(r.getId());
	}
	
	@RestConfig(configName = "根据id获取数据",method = MethodType.GET,url = "/getDocById")
	@Params({
		@Param(id = "id", name = "id字段",required=true),
	})
	public DocAndView getDocById(String id) throws Exception{
		Client client=ElasticsearchUtil.getClient();
		Document doc=ElasticsearchUtil.getDocById(client, index, type, id);
		return ViewUtil.getJsonView(doc);
	}
	
	@RestConfig(configName = "按条件查询数据",method = MethodType.POST,url = "/list")
	@Params({
		@Param(id = "index", name = "字段",required=true),
		@Param(id = "type", name = "值",required=true),
		@Param(id = "query", name = "查询条件{a:1,b:2}",required=true),
	})
	public DocAndView listDocs(String index,String type,String query) throws Exception{
		Client client=ElasticsearchUtil.getClient();
		Map<String, Object> map=JsonUtil.json2mapobj(query); 
		List<Document> docs=ElasticsearchUtil.listDocs(client, index, type, "age", true, "_id", 1000, 0, null, map);
		return ViewUtil.getJsonView(docs);
	}
	
	@RestConfig(configName = "查询数据",method = MethodType.POST,url = "/find")
	@Params({
		@Param(id = "index", name = "字段",required=true),
		@Param(id = "type", name = "值",required=true),
		@Param(id = "query", name = "查询条件{a:1,b:2}",required=true),
	})
	public DocAndView find(String index,String type,String query) throws Exception{
		Client client=ElasticsearchUtil.getClient();

		//获取链接
		SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index).setTypes(type);//要查询的index和type
		//searchRequestBuilder.addSort("num", SortOrder.ASC);//排序字段
		
		//构建sql and 查询语句 where a=1 and b=2
		Map<String, Object> map=new HashMap<String,Object>();
		map=JsonUtil.json2mapobj(query); 
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        if (map != null) {
            for (String key : map.keySet()) {
                queryBuilder.must(QueryBuilders.termQuery(key, map.get(key)));
            }
        }
		 
		 searchRequestBuilder.setQuery(queryBuilder); //添加查询语句
		
		 //设置最大值
		 searchRequestBuilder.setSize(1000);
	     searchRequestBuilder.setFrom(0);
		 
		 //开始执行查询
		 SearchResponse searchResponse = searchRequestBuilder.execute().actionGet();
		
		 //获取查询总数
		 SearchHits hits = searchResponse.getHits();
		 long total=hits.getTotalHits();
		 
		 //获取查询结果
		 List<Map<String, Object>> result = new ArrayList<>();
		 SearchHit[] searchHists = hits.getHits();
		 for (SearchHit sh : searchHists) {
	            Map<String, Object> dataMap = sh.getSourceAsMap();
	            dataMap.put("rowKey", sh.getId());
	            dataMap.put("tableName", sh.getIndex());
	            dataMap.put("type", sh.getType());
	            dataMap.put("version", sh.getVersion());
	            result.add(dataMap);
	     }
		 PrintUtil.o("total="+total);
		 
		return ViewUtil.getJsonView(result);
	}

	
	@RestConfig(configName = "插入一条json数据",method = MethodType.POST,url = "/insert")
	public DocAndView insertJsonStr() throws Exception{
		Client client=ElasticsearchUtil.getClient();		
		String jsonStr="{"+
				"    \"PromotionActiveDays\" : {\r\n" + 
				"        \"ActiveOnThursday\" : 1,\r\n" + 
				"        \"ActiveOnFriday\" : 1,\r\n" + 
				"        \"EndTime\" : \"23:59:00\",\r\n" + 
				"        \"ActiveOnMonday\" : 1,\r\n" + 
				"        \"ActiveOnSunday\" : 1,\r\n" + 
				"        \"StartTime\" : \"00:00:00\",\r\n" + 
				"        \"ActiveOnTuesday\" : 1,\r\n" + 
				"        \"ActiveOnSaturday\" : 1,\r\n" + 
				"        \"ActiveOnWednesday\" : 1\r\n" + 
				"    },\r\n" + 
				"    \"PromotionHeaderId\" : 9154,\r\n" + 
				"    \"PromotionsLevels\" : {\r\n" + 
				"        \"PromotionsLevel\" : {\r\n" + 
				"            \"Thresholds\" : {\r\n" + 
				"                \"Threshold\" : [ \r\n" + 
				"                    {\r\n" + 
				"                        \"ThresholdValue\" : 1,\r\n" + 
				"                        \"ThresholdTypeId\" : 5,\r\n" + 
				"                        \"BucketId\" : 1,\r\n" + 
				"                        \"ThresholdSubTypeId\" : 1000\r\n" + 
				"                    }, \r\n" + 
				"                    {\r\n" + 
				"                        \"ThresholdValue\" : 0,\r\n" + 
				"                        \"ThresholdTypeId\" : 5,\r\n" + 
				"                        \"BucketId\" : 2,\r\n" + 
				"                        \"ThresholdSubTypeId\" : 1103\r\n" + 
				"                    }, \r\n" + 
				"                    {\r\n" + 
				"                        \"ThresholdValue\" : \".25\",\r\n" + 
				"                        \"ThresholdTypeId\" : 4,\r\n" + 
				"                        \"BucketId\" : 3,\r\n" + 
				"                        \"ThresholdSubTypeId\" : 0\r\n" + 
				"                    }, \r\n" + 
				"                    {\r\n" + 
				"                        \"ThresholdValue\" : 1,\r\n" + 
				"                        \"ThresholdTypeId\" : 2,\r\n" + 
				"                        \"BucketId\" : 4,\r\n" + 
				"                        \"ThresholdSubTypeId\" : 0\r\n" + 
				"                    }\r\n" + 
				"                ]\r\n" + 
				"            },\r\n" + 
				"            \"Id\" : 1,\r\n" + 
				"            \"Reward\" : {\r\n" + 
				"                \"RewardTemplateId\" : 2,\r\n" + 
				"                \"ReduceMemberAccountScope\" : 1,\r\n" + 
				"                \"LimitItemCount\" : 0,\r\n" + 
				"                \"RewardValue\" : \".2\",\r\n" + 
				"                \"TimingScope\" : 0,\r\n" + 
				"                \"RewardValueType\" : 2,\r\n" + 
				"                \"ReduceMemberAccountValue\" : 1,\r\n" + 
				"                \"ReduceMemberAccountId\" : 1103,\r\n" + 
				"                \"RewardEnteredByCashier\" : 0,\r\n" + 
				"                \"LimitDiscountScope\" : 0\r\n" + 
				"            }\r\n" + 
				"        }\r\n" + 
				"    },\r\n" + 
				"    \"PromotionLoyaltySegments\" : {\r\n" + 
				"        \"PromotionLoyaltySegment\" : [ \r\n" + 
				"            {\r\n" + 
				"                \"ElementType\" : 1,\r\n" + 
				"                \"Exclude\" : 0,\r\n" + 
				"                \"LineId\" : 1,\r\n" + 
				"                \"SegmentId\" : 4\r\n" + 
				"            }, \r\n" + 
				"            {\r\n" + 
				"                \"ElementType\" : 0,\r\n" + 
				"                \"Exclude\" : 0,\r\n" + 
				"                \"LineId\" : 2,\r\n" + 
				"                \"SegmentId\" : 4\r\n" + 
				"            }, \r\n" + 
				"            {\r\n" + 
				"                \"ElementType\" : 1,\r\n" + 
				"                \"Exclude\" : 0,\r\n" + 
				"                \"LineId\" : 3,\r\n" + 
				"                \"SegmentId\" : 1\r\n" + 
				"            }, \r\n" + 
				"            {\r\n" + 
				"                \"ElementType\" : 1,\r\n" + 
				"                \"Exclude\" : 0,\r\n" + 
				"                \"LineId\" : 4,\r\n" + 
				"                \"SegmentId\" : 3\r\n" + 
				"            }, \r\n" + 
				"            {\r\n" + 
				"                \"ElementType\" : 0,\r\n" + 
				"                \"Exclude\" : 0,\r\n" + 
				"                \"LineId\" : 5,\r\n" + 
				"                \"SegmentId\" : 99\r\n" + 
				"            }, \r\n" + 
				"            {\r\n" + 
				"                \"ElementType\" : 1,\r\n" + 
				"                \"Exclude\" : 0,\r\n" + 
				"                \"LineId\" : 6,\r\n" + 
				"                \"SegmentId\" : 5\r\n" + 
				"            }, \r\n" + 
				"            {\r\n" + 
				"                \"ElementType\" : 1,\r\n" + 
				"                \"Exclude\" : 0,\r\n" + 
				"                \"LineId\" : 7,\r\n" + 
				"                \"SegmentId\" : 1\r\n" + 
				"            }, \r\n" + 
				"            {\r\n" + 
				"                \"ElementType\" : 1,\r\n" + 
				"                \"Exclude\" : 0,\r\n" + 
				"                \"LineId\" : 8,\r\n" + 
				"                \"SegmentId\" : 4\r\n" + 
				"            }, \r\n" + 
				"            {\r\n" + 
				"                \"ElementType\" : 1,\r\n" + 
				"                \"Exclude\" : 0,\r\n" + 
				"                \"LineId\" : 9,\r\n" + 
				"                \"SegmentId\" : 3\r\n" + 
				"            }, \r\n" + 
				"            {\r\n" + 
				"                \"ElementType\" : 0,\r\n" + 
				"                \"Exclude\" : 0,\r\n" + 
				"                \"LineId\" : 10,\r\n" + 
				"                \"SegmentId\" : 9\r\n" + 
				"            }, \r\n" + 
				"            {\r\n" + 
				"                \"ElementType\" : 1,\r\n" + 
				"                \"Exclude\" : 0,\r\n" + 
				"                \"LineId\" : 11,\r\n" + 
				"                \"SegmentId\" : 5\r\n" + 
				"            }\r\n" + 
				"        ]\r\n" + 
				"    },\r\n" + 
				"    \"PromotionDetails\" : {\r\n" + 
				"        \"Status\" : 1,\r\n" + 
				"        \"SegmentationMode\" : 1,\r\n" + 
				"        \"TypeId\" : 3,\r\n" + 
				"        \"PopulationSegmentsOperator\" : 1,\r\n" + 
				"        \"MemberRegistrationRequired\" : 0,\r\n" + 
				"        \"TriggerItemsExcludedFromOtherPromotions\" : 0,\r\n" + 
				"        \"DiscountAllocationScope\" : 3,\r\n" + 
				"        \"ManualPriorityValue\" : 76,\r\n" + 
				"        \"TriggerTiming\" : 0,\r\n" + 
				"        \"HeaderDescription\" : \"会员日5倍积分升值\",\r\n" + 
				"        \"MemberAccountId\" : 1103,\r\n" + 
				"        \"EndDate\" : \"2020-03-05T23:59:00\",\r\n" + 
				"        \"PopulationOfflineMode\" : 1,\r\n" + 
				"        \"StartDate\" : \"2020-02-26T00:00:00\",\r\n" + 
				"        \"ExcludeItemsWithProhibitDiscount\" : 0,\r\n" + 
				"        \"TargetPopulationType\" : 3,\r\n" + 
				"        \"PromotionReceiptDescription\" : \"会员日5倍积分升值\",\r\n" + 
				"        \"ExcludeTriggerItemsOfMarkedPromotions\" : 0,\r\n" + 
				"        \"RedemptionLimitPerTransaction\" : 100\r\n" + 
				"    },\r\n" + 
				"    \"PromotionsBuckets\" : {\r\n" + 
				"        \"PromotionsBucket\" : [ \r\n" + 
				"            {\r\n" + 
				"                \"ParticipateInReward\" : 1,\r\n" + 
				"                \"BucketEntity\" : [ \r\n" + 
				"                    {\r\n" + 
				"                        \"EntityId\" : 100070034,\r\n" + 
				"                        \"EntityType\" : 0,\r\n" + 
				"                        \"Exclude\" : 1,\r\n" + 
				"                        \"EntityValue\" : 0\r\n" + 
				"                    }, \r\n" + 
				"                    {\r\n" + 
				"                        \"EntityId\" : 100070035,\r\n" + 
				"                        \"EntityType\" : 0,\r\n" + 
				"                        \"Exclude\" : 1,\r\n" + 
				"                        \"EntityValue\" : 0\r\n" + 
				"                    }, \r\n" + 
				"                    {\r\n" + 
				"                        \"EntityId\" : 100070036,\r\n" + 
				"                        \"EntityType\" : 0,\r\n" + 
				"                        \"Exclude\" : 1,\r\n" + 
				"                        \"EntityValue\" : 0\r\n" + 
				"                    }, \r\n" + 
				"                    {\r\n" + 
				"                        \"EntityId\" : 100070037,\r\n" + 
				"                        \"EntityType\" : 0,\r\n" + 
				"                        \"Exclude\" : 1,\r\n" + 
				"                        \"EntityValue\" : 0\r\n" + 
				"                    }, \r\n" + 
				"                    {\r\n" + 
				"                        \"EntityId\" : 100403607,\r\n" + 
				"                        \"EntityType\" : 0,\r\n" + 
				"                        \"Exclude\" : 1,\r\n" + 
				"                        \"EntityValue\" : 0\r\n" + 
				"                    }, \r\n" + 
				"                    {\r\n" + 
				"                        \"EntityId\" : 100403610,\r\n" + 
				"                        \"EntityType\" : 0,\r\n" + 
				"                        \"Exclude\" : 1,\r\n" + 
				"                        \"EntityValue\" : 0\r\n" + 
				"                    }, \r\n" + 
				"                    {\r\n" + 
				"                        \"EntityId\" : 100558302,\r\n" + 
				"                        \"EntityType\" : 0,\r\n" + 
				"                        \"Exclude\" : 1,\r\n" + 
				"                        \"EntityValue\" : 0\r\n" + 
				"                    }, \r\n" + 
				"                    {\r\n" + 
				"                        \"EntityId\" : 100558303,\r\n" + 
				"                        \"EntityType\" : 0,\r\n" + 
				"                        \"Exclude\" : 1,\r\n" + 
				"                        \"EntityValue\" : 0\r\n" + 
				"                    }, \r\n" + 
				"                    {\r\n" + 
				"                        \"EntityId\" : 100558304,\r\n" + 
				"                        \"EntityType\" : 0,\r\n" + 
				"                        \"Exclude\" : 1,\r\n" + 
				"                        \"EntityValue\" : 0\r\n" + 
				"                    }, \r\n" + 
				"                    {\r\n" + 
				"                        \"EntityId\" : 100675702,\r\n" + 
				"                        \"EntityType\" : 0,\r\n" + 
				"                        \"Exclude\" : 1,\r\n" + 
				"                        \"EntityValue\" : 0\r\n" + 
				"                    }, \r\n" + 
				"                    {\r\n" + 
				"                        \"EntityId\" : 100675704,\r\n" + 
				"                        \"EntityType\" : 0,\r\n" + 
				"                        \"Exclude\" : 1,\r\n" + 
				"                        \"EntityValue\" : 0\r\n" + 
				"                    }, \r\n" + 
				"                    {\r\n" + 
				"                        \"EntityId\" : 100675705,\r\n" + 
				"                        \"EntityType\" : 0,\r\n" + 
				"                        \"Exclude\" : 1,\r\n" + 
				"                        \"EntityValue\" : 0\r\n" + 
				"                    }, \r\n" + 
				"                    {\r\n" + 
				"                        \"EntityId\" : 100746114,\r\n" + 
				"                        \"EntityType\" : 0,\r\n" + 
				"                        \"Exclude\" : 1,\r\n" + 
				"                        \"EntityValue\" : 0\r\n" + 
				"                    }, \r\n" + 
				"                    {\r\n" + 
				"                        \"EntityId\" : 100874708,\r\n" + 
				"                        \"EntityType\" : 0,\r\n" + 
				"                        \"Exclude\" : 1,\r\n" + 
				"                        \"EntityValue\" : 0\r\n" + 
				"                    }\r\n" + 
				"                ],\r\n" + 
				"                \"ThresholdAppliesTo\" : 0,\r\n" + 
				"                \"Id\" : 3,\r\n" + 
				"                \"AllocateDiscountBreakdown\" : 1\r\n" + 
				"            }, \r\n" + 
				"            {\r\n" + 
				"                \"ParticipateInReward\" : 0,\r\n" + 
				"                \"ThresholdAppliesTo\" : 101,\r\n" + 
				"                \"Id\" : 1,\r\n" + 
				"                \"AllocateDiscountBreakdown\" : 0,\r\n" + 
				"                \"MinimumRequiredValue\" : 1\r\n" + 
				"            }, \r\n" + 
				"            {\r\n" + 
				"                \"ParticipateInReward\" : 0,\r\n" + 
				"                \"ThresholdAppliesTo\" : 0,\r\n" + 
				"                \"Id\" : 2,\r\n" + 
				"                \"AllocateDiscountBreakdown\" : 0,\r\n" + 
				"                \"MinimumRequiredValue\" : 100\r\n" + 
				"            }, \r\n" + 
				"            {\r\n" + 
				"                \"ParticipateInReward\" : 0,\r\n" + 
				"                \"BucketEntity\" : [ \r\n" + 
				"                    {\r\n" + 
				"                        \"EntityId\" : 100090001,\r\n" + 
				"                        \"EntityType\" : 0,\r\n" + 
				"                        \"Exclude\" : 0,\r\n" + 
				"                        \"EntityValue\" : 0\r\n" + 
				"                    }\r\n" + 
				"                ],\r\n" + 
				"                \"ThresholdAppliesTo\" : 0,\r\n" + 
				"                \"Id\" : 4,\r\n" + 
				"                \"AllocateDiscountBreakdown\" : 0\r\n" + 
				"            }\r\n" + 
				"        ]\r\n" + 
				"    },\r\n" + 
				"    \"Store\" : {\r\n" + 
				"        \"StartDate\" : \"2020-03-05T00:00:00\",\r\n" + 
				"        \"Id\" : 100,\r\n" + 
				"        \"Suspended\" : 0,\r\n" + 
				"        \"EndDate\" : \"2020-03-05T23:59:00\"\r\n" + 
				"    }\r\n" + 
				"}";
		IndexResponse response = ElasticsearchUtil.saveDoc(client, "wastons", "productinfo", "PromotionHeaderId", DocumentUtil.json2doc(jsonStr));
		return ViewUtil.getJsonView(response.getResult());
	}
	
	@RestConfig(configName = "删除符合条件的数据",method = MethodType.POST,url = "/deletebyfieldvalue")
	public DocAndView deleteByFieldValue() throws Exception{
		Client client=ElasticsearchUtil.getClient();	
		int i=ElasticsearchUtil.deleteDocByFieldValue(client, index, type, "xb", "男");
		return ViewUtil.getJsonView(i);
	}
	
	
}
